//
//  RLoginReactor.swift
//  RxStudy
//
//  Created by TRS-Mobile on 2022/10/8.
//  Copyright © 2022 season. All rights reserved.
//

import Foundation

import RxSwift
import RxCocoa
import ReactorKit

class RLoginReactor: Reactor {
    enum Action {
        case inputName(String)
        case inputPwd(String)
        case login
    }
    
    enum Mutation {
        case setName(String)
        case setPwd(String)
        case setLogin(Bool)
        case setNameValid(Bool)
        case setPwdValid(Bool)
        case setValid(Bool)
    }
    
    struct State {
        var userName: String = ""
        var pwd: String = ""
        var isLogin: Bool = false
        var usernameValid: Bool = false
        var passwordValid: Bool = false
        var everythingValid: Bool = false
    }
    
    var initialState: State = State()
    let loginService: LoginServiceType
    
    init(initialState: State = State(), loginService: LoginServiceType) {
        self.initialState = initialState
        self.loginService = loginService
    }
    
    func mutate(action: Action) -> Observable<Mutation> {
        switch action {
        case .login:
            return loginService.login(name: currentState.userName, pwd: currentState.pwd)
                .map {.setLogin($0)}
        case .inputName(let name):
            let nameValid = Observable.just(Mutation.setNameValid(name.count == 11))
            return .concat([
                nameValid,
                .just(.setName(name)),
                .just(.setValid(currentState.passwordValid && name.count == 11))
            ])
        case .inputPwd(let pwd):
            return .concat([
                .just(.setPwdValid(pwd.count >= 6)),
                .just(.setPwd(pwd)),
                .just(.setValid(pwd.count >= 6 && currentState.usernameValid))
            ])
        }
    }
    
    func reduce(state: State, mutation: Mutation) -> State {
        var state = state
        switch mutation {
        case .setName(let name):
            state.userName = name
        case .setPwd(let pwd):
            state.pwd = pwd
        case .setLogin(let login):
            state.isLogin = login
        case .setNameValid(let valid):
            state.usernameValid = valid
        case .setPwdValid(let valid):
            state.passwordValid = valid
        case .setValid(let valid):
            state.everythingValid = valid
        }
        return state
    }
}

